package com.bang.study.day05.leetcode;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @Auther: Bang
 * @Date: 2019/9/17 0017 13:54
 * @Description: 677. 键值映射
 * 实现一个 MapSum 类里的两个方法，insert 和 sum。
 * <p>
 * 对于方法 insert，你将得到一对（字符串，整数）的键值对。字符串表示键，整数表示值。如果键已经存在，那么原来的键值对将被替代成新的键值对。
 * <p>
 * 对于方法 sum，你将得到一个表示前缀的字符串，你需要返回所有以该前缀开头的键的值的总和。
 * <p>
 * 示例 1:
 * <p>
 * 输入: insert("apple", 3), 输出: Null
 * 输入: sum("ap"), 输出: 3
 * 输入: insert("app", 2), 输出: Null
 * 输入: sum("ap"), 输出: 5
 */
public class MapSum {

    private class Node {

        public int value;

        public HashMap<Character, Node> next;

        public Node() {
            next = new HashMap<>();
            value = 0;
        }

        public Node(int value) {
            this.value = value;
            next = new HashMap<>();
        }
    }

    private Node root;


    public MapSum() {
        root = new Node();
    }

    public void insert(String key, int val) {
        Node curr = root;
        for (int i = 0; i < key.length(); i++) {
            char c = key.charAt(i);
            if (!curr.next.containsKey(c)) {
                curr.next.put(c, new Node());
            }
            curr = curr.next.get(c);
        }
        curr.value = val;
    }

    public int sum(String prefix) {
        Node curr = root;
        for (int i = 0; i < prefix.length(); i++) {
            char c = prefix.charAt(i);
            if (!curr.next.containsKey(c)) {
                curr.next.put(c, new Node());
            }
            curr = curr.next.get(c);
        }
        return sum(curr);

    }

    private int sum(Node node) {
        int res = node.value;
        HashMap<Character, Node> next = node.next;
        for (Character character : next.keySet()) {
            res += sum(next.get(character));
        }
        return res;
    }


    public static void main(String[] args) {
        MapSum mapSum = new MapSum();
        mapSum.insert("apple", 3);
        System.out.println(mapSum.sum("ap"));

        mapSum.insert("app", 2);
        System.out.println(mapSum.sum("ap"));
    }
}
